#----coding:utf-8-----
import tornado.ioloop
import tornado.web
from urllib.parse import unquote
from FunctionTool import RemoveModules
import json,time
import gc,sys,os
import SolrCache
import threading
from concurrent.futures import ProcessPoolExecutor as PPool

FrequencyDict = None
FrequencySpaces = None
FrequencyTargets = None
FrequencyAttrs = None
SklearnOrigin = None
SklearnOriginType = None
IDocument = None

IsTest = True
try:
    if sys.argv[1] == "1" or sys.argv[1] == 1:
        IsTest = False
except:
    IsTest = True
IsTraining = False


__cache=None
def CurrentCache():
    global __cache
    if __cache is None:
       __cache = SolrCache.Cache()
    return __cache

# 词频查询函数
def FQuery(toparam):
    global FrequencyDict,FrequencySpaces,FrequencyTargets,FrequencyAttrs,IDocument
    result, modulesNames = "", ["FrequencyQuery", "ExecMatchResult"]
    try:
        param = toparam()

        FQuery = __import__(modulesNames[0])
        fquery = FQuery.Query(
            FrequencyDict,
            FrequencySpaces,
            FrequencyTargets,
            FrequencyAttrs
        )

        RQuery = __import__(modulesNames[1])
        fquery = RQuery.HandleRequest(param, fquery.query, IDocument)

        result = fquery.Handle()
        result = json.dumps(result, ensure_ascii=False)
    except Exception as e:
        result = str(e)
    finally:
        for name in modulesNames:
            RemoveModules(name)
    return result

# 匹配查询函数
def MQuery(toparam):
    global cache
    modulesName = "RecursionQuery"
    try:
        param = toparam()
        Query = __import__(modulesName).Query(param, SQuery, CurrentCache())
        result = Query.mquery(lambda x: json.loads(FQuery(lambda :x)))
        result = json.dumps(result, ensure_ascii=False)
    except Exception as e:
        result = str(e)
    finally:
        RemoveModules(modulesName)
        
    return result

# 朴素贝叶斯查询接口
def SQuery(ta, case_type):
    global SklearnOrigin, SklearnOriginType
    modulesName = "SklearnQuery"
    w,p,pa = 0,0,[]
    try:
        Query = __import__(modulesName).Query(SklearnOrigin, SklearnOriginType)
        w,p,pa = Query.query (ta, case_type)
    except Exception as e:
        print(str(e))
    finally:
        RemoveModules(modulesName)

    return w,p,pa

# 词频查询
class FrequencyHandle(tornado.web.RequestHandler):
    def get(self, *args, **kwargs):
        uri = self.request.uri
        uri = str(unquote(uri, 'utf-8'))
        result = FQuery(lambda : uri.split("?")[1])

        self.write(result)

    def post(self, *args, **kwargs):
        result = FQuery(lambda : bytes.decode(self.request.body))

        self.write(result)

    def write_error(self, status_code, **kwargs):
        self.write('Detect Error %s' % status_code)

# exec
class ExecHandle(tornado.web.RequestHandler):
    def get(self, *args, **kwargs):
        self.write("fail")

    def post(self, *args, **kwargs):
        execContent = bytes.decode(self.request.body)
        result = "success"
        try:
            exec(execContent)
        except Exception as e:
            result = str(e)
        self.write(result)

# match
class MatchHandle(tornado.web.RequestHandler):
    def post(self):
        result = MQuery(lambda :bytes.decode(self.request.body))
        self.write (result)

    def write_error(self, status_code, **kwargs):
        self.write('Detect Error %s' % status_code)

class CacheHandle(tornado.web.RequestHandler):
    def get(self, *args, **kwargs):
        CurrentCache().clear()
        self.write("success")

# 词频统计训练
def FrequencyTrain():
    modulesName = "FrequencyCount"
    dic,spaces,targets,attrs=None,None,None,None
    try:
        dic,spaces,targets,attrs=__import__(modulesName).AutoTrain()
    except Exception as e:
        print(str(e))
    finally:
        RemoveModules(modulesName)
    return dic,spaces,targets,attrs

# 朴素贝叶斯训练
def SklearnTrain():
    modulesName = "Buildsklearn"
    origin,origintype = None,None
    try:
        sklearn = __import__(modulesName)
        origin = sklearn.train()
        origintype = sklearn.gresult
    except:
        pass
    finally:
        RemoveModules(modulesName)

    return origin,origintype

# 逆文献频率训练
def IDocumentTrain():
    modulesName = "traindata"
    result = None
    try:
        IDoc = __import__(modulesName)
        result = IDoc.allTF_IDF()
    except:
        result = None
    finally:
        RemoveModules(modulesName)

    return result

def AutoFrequency():
    global FrequencyDict, FrequencySpaces, FrequencyTargets, FrequencyAttrs
    FrequencyDict, FrequencySpaces, FrequencyTargets, FrequencyAttrs = FrequencyTrain()

def AutoSklearn():
    global SklearnOrigin, SklearnOriginType
    SklearnOrigin, SklearnOriginType=SklearnTrain()

def AutoIDocument():
    global IDocument
    IDocument=IDocumentTrain()

def AutoTrain():
    global IsTraining
    if IsTraining:
        return
    IsTraining = True
    begintime = time.time()
    '''词频统计'''
    AutoFrequency()
    print("词频统计", time.time() - begintime)
    begintime = time.time()
    '''朴素贝叶斯'''
    AutoSklearn()
    print("朴素贝叶斯", time.time() - begintime)
    begintime = time.time()
    '''逆文献频率'''
    AutoIDocument()
    print("逆文献频率", time.time() - begintime)
    IsTraining = False

def killSelfPort():
    try:
        results = {x[1] for x in [[temp for temp in item.strip().split(' ') if temp.strip() != ''] for item in os.popen('lsof -i:8887').read().split('\n') if item.strip() != ''] if x[0] == 'python3'}
        for result in results:
            while True:
                if os.system('kill {0}'.format(result)) == 0:
                    break
        if len(results) > 0:
            time.sleep(30)
    except:
        pass
if __name__ == "__main__":
    AutoTrain ()
    killSelfPort()
    app = tornado.web.Application(
        [
            (r"/", FrequencyHandle),
            (r"/exec", ExecHandle),
            (r"/match", MatchHandle),
            (r"/cache/clear", CacheHandle)
        ]
    )
    app.listen(8887)
    print('服务启动完毕')
    tornado.ioloop.IOLoop.current().start()